package io.wanghaoran.project.module.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.wanghaoran.project.common.annotation.CrudLog;
import io.wanghaoran.project.common.base.controller.BaseController;
import io.wanghaoran.project.common.base.domain.Result;
import io.wanghaoran.project.common.base.domain.TableDataInfo;
import io.wanghaoran.project.common.base.domain.XmSelectNode;
import io.wanghaoran.project.common.enums.BusinessType;
import io.wanghaoran.project.framework.security.util.SecurityUtils;

import io.wanghaoran.project.module.system.entity.SysUser;
import io.wanghaoran.project.module.system.model.dto.ModifyPassDTO;
import io.wanghaoran.project.module.system.model.dto.RegisterDTO;
import io.wanghaoran.project.module.system.model.dto.ResetPassDTO;
import io.wanghaoran.project.module.system.model.dto.UserParamDTO;
import io.wanghaoran.project.module.system.service.SysUserService;
import io.wanghaoran.project.module.system.service.UserTokensLogService;
import io.wanghaoran.project.module.system.service.UserTokensService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.*;

import org.thymeleaf.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

/**
 * @description: 用户控制层
 */
@Api(tags = "用户表")
@Controller
@RequestMapping("/system/sysUser")
@RequiredArgsConstructor
public class SysUserController extends BaseController {

    private static final String SUFFIX = "system/sysUser";

    private final SysUserService sysUserService;
    private final UserTokensService userTokensService;
    private final UserTokensLogService userTokensLogService;


    @Resource
    private BCryptPasswordEncoder passwordEncoder;




    private String redisHost = "172.16.52.23";

    /**
     * @return
     * @Author ljc
     * @Description 注册/页面返回
     * @Date 11:09 2025/7/29
     * @Param
     **/
    @GetMapping("/registerPage")
    public String registerPage() {
        return SUFFIX+"/register";
    }


    @PostMapping("/register")
    @ResponseBody
    public Result register(@RequestBody RegisterDTO registerDTO) {

        if (StringUtils.isEmpty(registerDTO.getEmail())) {
            return Result.failure("错误：邮箱为空");
        }
        JedisPool pool = new JedisPool(redisHost, 6379);
        Jedis jedis = pool.getResource();
        String codeValue = jedis.get(registerDTO.getEmail());

        if (StringUtils.isEmpty(codeValue)) {
            return Result.failure("错误：验证码已过期");
        }
        if (!codeValue.equals(registerDTO.getCode())) {
            return Result.failure("错误：验证码错误");
        }

        List<SysUser> getlist = sysUserService.getListUserName(registerDTO);
        List<SysUser> listPhoneNumber = sysUserService.getListPhoneNumber(registerDTO);
        List<SysUser> listEmail = sysUserService.getListEmail(registerDTO);
        //校验唯一性
        if (!listPhoneNumber.isEmpty()) {
            return Result.failure("错误：手机号已注册");
        }

        if (!getlist.isEmpty()) {
            return Result.failure("错误：账号已被注册");
        }

        if (!listEmail.isEmpty()) {
            return Result.failure("错误：邮箱已被注册");
        }

        SysUser sysUser = new SysUser();
        sysUser.setPassWord(registerDTO.getPassword());
        sysUser.setUserName(registerDTO.getUserName());
        sysUser.setPhonenumber(registerDTO.getPhonenumber());
        sysUser.setEmail(registerDTO.getEmail());

        sysUser.setEnabled("N");
        //默认值
        sysUser.setRoleIds("3");
        //部门ID
        sysUser.setDeptId(26L);
        sysUser.setCreateBy("mine");
        sysUserService.addUser(sysUser);

        jedis.close();
        return Result.success();
    }


    /**
     * @return
     * @Author ljc
     * @Description 忘记密码
     * @Date 11:09 2025/7/29
     * @Param
     **/
    @GetMapping("/forgotPasswordPage")
    public String forgotPasswordPage() {

        return SUFFIX+"/forgotPassword";
    }


    @GetMapping("/forgotPassword")
    @ResponseBody
    public Result forgotPassword(RegisterDTO registerDTO) {

        SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, registerDTO.getUserName()));

        if (sysUser == null) {
            return Result.failure("错误：没有找到用户");
        }
        if (!sysUser.getEmail().equals(registerDTO.getEmail())) {
            return Result.failure("错误：该账户与邮箱不匹配");
        }

        JedisPool pool = new JedisPool(redisHost, 6379);
        Jedis jedis = pool.getResource();
        String codeValue = jedis.get(registerDTO.getEmail());
        if (StringUtils.isEmpty(codeValue)) {
            return Result.failure("错误：验证码已过期");
        }

        if (!codeValue.equals(registerDTO.getCode())) {
            return Result.failure("错误：验证码错误");
        }
        jedis.close();

        sysUser.setPassWord(passwordEncoder.encode(registerDTO.getPassword()));
        sysUserService.updateById(sysUser);
        return Result.success();
    }


    /**
     * @return
     * @Author ljc
     * @Description 发送验证
     * @Date 11:09 2025/7/29
     * @Param
     **/
    @GetMapping("/send")
    @ResponseBody
    public Result send(String toEmail) throws MessagingException {

        Random rand = new Random();
        int randomNum = rand.nextInt(900000) + 100000;
        JedisPool pool = new JedisPool(redisHost, 6379);
        Jedis jedis = pool.getResource();
        jedis.set(toEmail, String.valueOf(randomNum));
        jedis.expire(toEmail, 3600);
        jedis.close();
        String text = "您的AI智能助手验证码为" + randomNum + "，请勿告知他人！";
        senEmail(toEmail, text);
        return Result.success();
    }


    /**
     * 跳转到用户信息
     *
     * @return 用户信息页面
     */
    @GetMapping("/userInfoPage")
    public String userInfoPage(ModelMap map) {
        String userName = SecurityUtils.getUserName();
        SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName));
        map.put("sysUser", sysUser);
        return SUFFIX + "/userInfo";
    }

    /**
     * 跳转到修改密码
     *
     * @return 修改密码页面
     */
    @GetMapping("/modifyPassPage")
    public String modifyPassPage(ModelMap map) {
        String userName = SecurityUtils.getUserName();
        SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName));
        map.put("sysUser", sysUser);
        return SUFFIX + "/modifyPass";
    }

    /**
     * 跳转列表
     *
     * @return 列表页面
     */
    @GetMapping("/listPage")
    public String listPage() {
        return SUFFIX + "/list";
    }

    /**
     * 跳转添加
     *
     * @return 添加页面
     */
    @GetMapping("/addPage")
    public String addPage() {
        return SUFFIX + "/add";
    }

    /**
     * 跳转编辑
     *
     * @param id 用户id
     * @return 编辑页面
     */
    @GetMapping("/editPage/{id}")
    public String editPage(@Valid @NotNull(message = "id不能为空") @PathVariable Long id, ModelMap map) {
        SysUser sysUser = sysUserService.detail(id);
        map.put("sysUser", sysUser);
        return SUFFIX + "/edit";
    }

    /**
     * 重置密码
     *
     * @param resetPassDTO 重置用户密码对象
     * @return 提示
     */
    @CrudLog(title = "重置密码", businessType = BusinessType.UPDATE)
    @PreAuthorize("hasAuthority('user:edit')")
    @PostMapping("/resetPass")
    @ResponseBody
    public Result resetPass(@RequestBody @Validated ResetPassDTO resetPassDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return Result.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        String msg = sysUserService.resetPass(resetPassDTO);
        return Result.success(msg);
    }

    /**
     * 修改密码
     *
     * @param modifyPassDTO 修改密码对象
     * @return 修改状态
     */
    @CrudLog(title = "修改密码", businessType = BusinessType.UPDATE)
//    @PreAuthorize("hasAuthority('user:edit')")
    @PostMapping("/modifyPass")
    @ResponseBody
    public Result modifyPass(@RequestBody @Validated ModifyPassDTO modifyPassDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return Result.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        boolean flag = sysUserService.modifyPass(modifyPassDTO);
        return Result.success(flag);
    }

    /**
     * 列表请求
     *
     * @param userParamDTO 用户列表对象
     * @return 请求列表
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "limit", value = "每页记录数", dataType = "Integer", paramType = "query")
    })
    @PreAuthorize("hasAuthority('user:list')")
    @GetMapping("/page")
    @ResponseBody
    public TableDataInfo page(UserParamDTO userParamDTO) {
        startPage();
        List<SysUser> list = sysUserService.list(userParamDTO);
        return getDataTable(list);
    }

    /**
     * 添加请求
     *
     * @param sysUser 添加用户对象
     * @return 添加状态
     */
    @CrudLog(title = "添加用户", businessType = BusinessType.INSERT)
    @PreAuthorize("hasAuthority('user:add')")
    @PostMapping("/add")
    @ResponseBody
    public Result add(@RequestBody @Validated SysUser sysUser, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return Result.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        sysUser.setPassWord("123456");
        String msg = sysUserService.addUser(sysUser);
        return Result.success(msg);
    }

    /**
     * 编辑请求
     *
     * @param sysUser 编辑用户对象
     * @return 编辑状态
     */
    @CrudLog(title = "更新用户", businessType = BusinessType.UPDATE)
    @PreAuthorize("hasAuthority('user:edit')")
    @PostMapping("/edit")
    @ResponseBody
    public Result edit(@RequestBody @Validated SysUser sysUser, BindingResult bindingResult) throws MessagingException {
        if (bindingResult.hasErrors()) {
            return Result.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        sysUserService.edit(sysUser);
        SysUser user = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getId,sysUser.getId()));
        //发送验证码
        if (!StringUtils.isEmpty(sysUser.getEnabled()) && "Y".equals(sysUser.getEnabled())) {
            senEmail(user.getEmail(),"你的账号已激活可正常使用！");
        }

        return Result.success();
    }

    /**
     * 编辑用户信息请求
     *
     * @param sysUser 编辑用户对象
     * @return 编辑状态
     */
    @CrudLog(title = "更新个人信息", businessType = BusinessType.UPDATE)
//    @PreAuthorize("hasAuthority('user:edit')")
    @PostMapping("/editUserInfo")
    @ResponseBody
    public Result editUserInfo(@RequestBody @Validated SysUser sysUser, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return Result.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        boolean flag = sysUserService.updateById(sysUser);
        return Result.success(flag);
    }


    @ApiOperation(value = "用户删除(单个条目)")
    @PreAuthorize("hasAuthority('user:del')")
    @DeleteMapping(value = "/remove/{id}")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    @CrudLog(title = "删除用户", businessType = BusinessType.DELETE)
    public Result remove(@Valid @NotNull(message = "id不能为空") @PathVariable Long id) {
        String userName = sysUserService.getById(id).getUserName();
        sysUserService.remove(id);
        // 根据username删除userTokens表中对应的记录
        userTokensService.removeByUserName(userName);
        // 根据username删除userTokensLog表中对应的记录
        userTokensLogService.removeByUserName(userName);
        return Result.success();
    }

    @ApiOperation(value = "用户删除(多个条目)")
    @PreAuthorize("hasAuthority('user:del')")
    @PostMapping(value = "/removes")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    @CrudLog(title = "删除用户", businessType = BusinessType.DELETE)
    public Result removes(@RequestBody @Valid List<Long> ids) {
        for (Long id : ids) {
            String userName = sysUserService.getById(id).getUserName();
            // 根据username删除userTokens表中对应的记录
            userTokensService.removeByUserName(userName);
            // 根据username删除userTokensLog表中对应的记录
            userTokensLogService.removeByUserName(userName);
        }
        sysUserService.removes(ids);
        return Result.success();
    }

    /**
     * 导出用户信息
     */
    @RequestMapping("/exportExcel")
    public void export(HttpServletRequest request, HttpServletResponse response) {
        sysUserService.exportSysUser(response);
    }

    /**
     * 根据用户ids查询选中用户树结构
     *
     * @param ids 用户id列表
     * @return 用户树结构
     */
    @GetMapping("/xmSelect")
    @ResponseBody
    public Result xmSelect(@RequestParam(value = "ids", required = false) String ids) {
        List<XmSelectNode> xmSelectNodes = sysUserService.xmSelect(ids);
        return Result.success(xmSelectNodes);
    }


    /**
     * @return java.lang.Boolean
     * @Author ljc
     * @Description 邮件发送
     * @Date 10:03 2025/7/30
     * @Param [toEmail, text]
     **/
    public Boolean senEmail(String toEmail, String text) throws MessagingException {

        final String fromEmail = "biad_ai@163.com";
        // 邮箱密码或授权码（视服务商要求）
        final String password = "WLTGtcrBaZaswRyQ";

        // 配置SMTP服务器属性
        Properties properties = new Properties();
        properties.put("mail.smtp.host", "smtp.163.com");
        properties.put("mail.smtp.port", "465"); // 或使用465（SSL模式）
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.ssl.enable", "true"); // 若需SSL加密

        // 创建会话和邮件消息
        Session session = Session.getInstance(properties);
        Transport transport = session.getTransport();
        transport.connect(fromEmail, password);
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(fromEmail));
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
        message.setSubject("北京建筑设计研究院AI智能助手");
        message.setText(text);

        // 发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
        return true;
    }

}
